import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { z } from 'zod';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { UserService } from '../services/UserService';

// 请求体验证 schema
const registerSchema = z.object({
  username: z.string().min(3, '用户名至少3个字符').max(20, '用户名最多20个字符'),
  email: z.string().email('邮箱格式不正确'),
  password: z.string().min(6, '密码至少6个字符').max(50, '密码最多50个字符'),
});

const loginSchema = z.object({
  email: z.string().email('邮箱格式不正确'),
  password: z.string().min(1, '密码不能为空'),
});

// 类型定义
interface RegisterBody {
  username: string;
  email: string;
  password: string;
}

interface LoginBody {
  email: string;
  password: string;
}

interface JWTPayload {
  userId: number;
  email: string;
}

export default async function authRoutes(fastify: FastifyInstance) {
  const userService = new UserService();

  // 用户注册
  fastify.post<{ Body: RegisterBody }>('/register', {
    schema: {
      description: '用户注册',
      tags: ['认证'],
      body: {
        type: 'object',
        required: ['username', 'email', 'password'],
        properties: {
          username: { type: 'string', minLength: 3, maxLength: 20 },
          email: { type: 'string', format: 'email' },
          password: { type: 'string', minLength: 6, maxLength: 50 },
        },
      },
      response: {
        201: {
          type: 'object',
          properties: {
            success: { type: 'boolean' },
            message: { type: 'string' },
            data: {
              type: 'object',
              properties: {
                id: { type: 'number' },
                username: { type: 'string' },
                email: { type: 'string' },
                createdAt: { type: 'string' },
              },
            },
          },
        },
        400: {
          type: 'object',
          properties: {
            success: { type: 'boolean' },
            message: { type: 'string' },
          },
        },
      },
    },
  }, async (request: FastifyRequest<{ Body: RegisterBody }>, reply: FastifyReply) => {
    try {
      // 验证请求体
      const validatedData = registerSchema.parse(request.body);

      // 检查邮箱是否已存在
      const existingUser = await userService.findByEmail(validatedData.email);
      if (existingUser) {
        return reply.status(400).send({
          success: false,
          message: '邮箱已被注册',
        });
      }

      // 创建用户
      const user = await userService.create(validatedData);

      return reply.status(201).send({
        success: true,
        message: '注册成功',
        data: {
          id: user.id,
          username: user.username,
          email: user.email,
          createdAt: user.createdAt,
        },
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        return reply.status(400).send({
          success: false,
          message: '请求参数验证失败',
          errors: error.errors,
        });
      }

      fastify.log.error(error);
      return reply.status(500).send({
        success: false,
        message: '注册失败',
      });
    }
  });

  // 用户登录
  fastify.post<{ Body: LoginBody }>('/login', {
    schema: {
      description: '用户登录',
      tags: ['认证'],
      body: {
        type: 'object',
        required: ['email', 'password'],
        properties: {
          email: { type: 'string', format: 'email' },
          password: { type: 'string', minLength: 1 },
        },
      },
      response: {
        200: {
          type: 'object',
          properties: {
            success: { type: 'boolean' },
            message: { type: 'string' },
            data: {
              type: 'object',
              properties: {
                token: { type: 'string' },
                user: {
                  type: 'object',
                  properties: {
                    id: { type: 'number' },
                    username: { type: 'string' },
                    email: { type: 'string' },
                  },
                },
              },
            },
          },
        },
        401: {
          type: 'object',
          properties: {
            success: { type: 'boolean' },
            message: { type: 'string' },
          },
        },
      },
    },
  }, async (request: FastifyRequest<{ Body: LoginBody }>, reply: FastifyReply) => {
    try {
      // 验证请求体
      const validatedData = loginSchema.parse(request.body);

      // 查找用户
      const user = await userService.findByEmail(validatedData.email);
      if (!user) {
        return reply.status(401).send({
          success: false,
          message: '邮箱或密码错误',
        });
      }

      // 验证密码
      const isPasswordValid = await bcrypt.compare(validatedData.password, user.password);
      if (!isPasswordValid) {
        return reply.status(401).send({
          success: false,
          message: '邮箱或密码错误',
        });
      }

      // 生成 JWT token
      const jwtSecret = process.env.JWT_SECRET;
      if (!jwtSecret) {
        throw new Error('JWT_SECRET 环境变量未设置');
      }

      const payload: JWTPayload = {
        userId: user.id,
        email: user.email,
      };

      const token = jwt.sign(payload, jwtSecret, {
        expiresIn: process.env.JWT_EXPIRES_IN || '7d',
      } as jwt.SignOptions);

      return reply.send({
        success: true,
        message: '登录成功',
        data: {
          token,
          user: {
            id: user.id,
            username: user.username,
            email: user.email,
          },
        },
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        return reply.status(400).send({
          success: false,
          message: '请求参数验证失败',
          errors: error.errors,
        });
      }

      fastify.log.error(error);
      return reply.status(500).send({
        success: false,
        message: '登录失败',
      });
    }
  });
}